package cn.king.springframework.beans.factory.support;

import cn.king.springframework.beans.BeanException;
import cn.king.springframework.beans.factory.BeanFactory;
import cn.king.springframework.beans.factory.config.BeanDefinition;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description:TODO
 * @Author:wangkun
 * @ClassName:AbstractBeanFactory
 * @Package:cn.king.springframework.beans.factory.support
 * @Date:2022年04月09日 22:02
 * @Version:1.0
 * @Project:simple-spring
 */
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
    @Override
    public Object getBean(String beanName) throws BeanException {
        return doGetBean(beanName,null);
    }

    @Override
    public Object getBean(String beanName, Object... args) {

        return doGetBean(beanName,args);
    }


    /**
     * 获取一个bean，如果不存在,则根据beandefinition实例化一个bean并
     * 缓存起来,初始化时可定不会用new的方式,会根据beandefinition的描述来
     * 构建一个对象
     * @param beanName
     * @param args
     * @param <T>
     * @return
     */
    protected <T> T doGetBean(final String beanName,final Object[] args){
        Object bean = getSingleton(beanName);
        if(null != bean){
            return (T)bean;
        }
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        return (T)createBean(beanName,beanDefinition,args);
    }

    /**
     * 模板方法，由具体的子类实现
     * @param beanName
     * @return
     * @throws BeanException
     */
    protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeanException;

    protected abstract Object createBean(String beanName,BeanDefinition beanDefinition,Object[] objects) throws BeanException;
}
